Russian Roulette & Importance Sampling

对于Path Tracing中的最重要思想Russian Roulette & Importance Sampling,因为老是忘,所以这次尝试用更加简单无脑的语言总结一下。


Importance Sampling

先来说蒙特卡洛积分

传统的思想是黎曼积分,把每个小面积加起来,然后无限细分就会逼近真实值:

slice1@2x

在定义域上均匀采样,采采采,每次都算整个定义域的面积,然后平均一下,随着采样数的增加,就可以逼近真实值,这是最简单的蒙特卡洛积分:

slice2@2x

那么重要性采样是要解决一个什么问题呢?

引用一下我上一篇文章的话:

蒙特卡洛积分中,可以使用均匀采样和重要性采样。两种采样方式的积分结果期望是相同的,均随样本量的增加收敛于真实值,也就是说两种采样方式都是正确而无偏的。所以,重要性采样的目的在于,在同样的采样数下有效减少积分结果的方差,即积分结果更加收敛于真实值。

其实就是在比较少的采样数下,得到更逼近真实值的结果

怎么做呢?

一个直观的想法是:多采值大的,少采值小的,就可以更快逼近。对应到Path Tracing中就是多采亮的地方,少采暗的地方,想想就觉得很对。

就像下图这样:

slice3@2x

但是这样加起来的结果,直接平均明显不对,明显偏大,怎么办?很简单,把采样概率除掉再平均不就好了。

slice4@2x

多采值大的,少采值小的这个思路是没问题了。

那么什么情况下逼近最快呢?想想应该是直接把原函数作为采样的PDF(概率密度函数)时是最理想的。

那么问题来了,我就是不知道原函数长啥样才用的蒙特卡洛积分啊。

(这步是我猜的)简单,先均匀采样一遍描出来个近似的函数,然后作为PDF扔进去不就行了,其实也差不了多少:

slice5@2x

重要性采样就是这么简单。


Russian Roulette

下面我们要解决什么问题呢?

Path Tracing不知道什么时候停止追踪的问题。

当然我第一脑子肯定能想到,设置个阈值,能量小于0.0001的时候就停止,不就行了吗。

但是这样带来的渲染结果就是,总比真实值要暗那么一点点。(又不是不能用)

在Path Tracing中,理论上光线需要递归弹射无数次,我们无论怎样设置截断次数都将得到一个理论上不正确的值。

其实有更聪明的做法:

使用Russian Roulette可以非常巧妙的解决这一问题:对于一次光线弹射,设定以概率 $P$ 打出光线并计算结果,而概率 $1-P$ 不打出光线。将打出光线的计算结果除以 $P$ ,则其期望为理论正确值 $L_o$ 。对一次弹射而言这种处理毫无意义且引入误差,而对于多次计算则大不相同,对于同一条光线多次多层递归计算后的结果求期望,其结果依概率收敛于光线进行无穷次弹射的正确值。

对于一束光线,需要计算 $n$ 次弹射的概率为 $P^n$ ,随 $n$ 的增大而趋于零,这使得该递归算法总能终止。 $P$ 越小时算法终止越快,性能越好,计算结果随机误差越大;$P=1$ 时相当于原始思路,光线将会弹射无数次,递归算法无法终止。

image-20200917155206714

完了,我自己写的我都看不懂,智商果真又下降了。

那么我们从头再来。

我们的目的是什么?让Path Tracing不会无限追踪下去,同时还能逼近真实值

那么我们这样可以吗?每一步都以0.8的概率继续追踪,0.2的概率放弃追踪,这样追踪至少1次的概率为0.8,2次为0.64,3次为0.8 ^ 3,后面总有一次会停止追踪,无限追踪的概率为0。这不就解决了无限追踪的问题吗?我可真是个小机灵鬼。

但是这样一来,我们的结果不就远小于真实值了吗?

没关系,我们想想,多次采样后,我们的结果肯定就是真实值的大约0.8倍啊(其实不是,应该是小于0.8的一个值),再把0.8给他除掉不就行了。

仔细一想,明显不应该直接只在最后的结果上除,而是在每一步递归返回的结果上都要除,因为每一步都是0.8概率继续追踪。

完美。

对于一次采样的一次追踪而言,这样做明显是错的离谱,因为得到的要么是真实值的1 / 0.8 = 1.25倍,要么是0 / 0.8 = 0。但是对于大量采样,这样做的结果是1.25 * 0.8 + 0 * 0.2 = 1,绝了。

世界上怎么会有这么聪明的人,我好嫉妒。

学术点的说法是我以前写的:

这一方法成功将截断误差消除在是否打出光线的随机性中,系统误差化为随机误差,从而得到了正确无偏的值。

太妙了,总感觉这个思路将来可以用于解决其他问题。


总结

最后我发现了这两种方法共同的思路:

对于大量采样而言,先给它加个概率,然后再在结果中除掉不就行了。

希望我以后也能提出类似的方法,然后对自己说出:“我好聪明”。